"""
[课程内容]: Python批量下载抖音视频无水印内容 https://www.douyin.com/

[授课老师]: 青灯教育-自游老师   [授课时间]: 20:05 可以点歌  可以问问题

[环境使用]:
    Python 3.8
    Pycharm

[模块使用]:
    requests --> pip install requests
    selenium --> pip install selenium==3.141.0
    json
    re
---------------------------------------------------------------------------------------------------
win + R 输入cmd 输入安装命令 pip install 模块名 (如果你觉得安装速度比较慢, 你可以切换国内镜像源)
先听一下歌 等一下后面进来的同学,20:05正式开始讲课 [有什么喜欢听得歌曲 也可以在公屏发一下]
相对应的安装包/安装教程/激活码/使用教程/学习资料/工具插件 可以加木子老师微信python10080
需要抖音js逆向案例教学 --> 加木子老师微信 python10080 领取
---------------------------------------------------------------------------------------------------
写过爬虫 -> 1
没有写过 -> 0

案例分为两部分讲解:
    1. 采集单个视频内容
    2. 采集多个视频内容 <某个视频博主所有的视频内容>

爬虫流程:

一. 数据来源分析
    1. 明确需求: 明确采集的网站以及数据内容
        - 网址: https://www.douyin.com/user/MS4wLjABAAAAkzRSrOuSsM4Z1Ricsddumx_aSvX0jmOPcQR2qTs3PEtImBD8BomLrqvtIOBKOL0P
        - 数据: 视频内容 抖音视频 <链接地址url>
    2. 抓包分析: 一定要先分析数据在什么地方可以获得 <浏览器上面进行操作>
        - 打开开发者工具: F12
        - 刷新网页 <点击一个视频内容播放>
            看到开发者工具面板上面有很多数据包进行加载
        - 找视频链接地址: 点击 媒体 media
            视频链接: https://v3-web.douyinvod.com/bbeb8e1e58b231d023346e90d36f4a97/654637a1/video/tos/cn/tos-cn-ve-15c001-alinc2/o0JyOfLfhAobsfmHsEncePwLtAEsAezVqXJwxY/?a=6383&ch=10010&cr=3&dr=0&lr=all&cd=0%7C0%7C0%7C3&cv=1&br=757&bt=757&cs=2&ds=3&ft=bvTKJbQQqU-mfJ4ZPo0OW_EklpPiXI94AFVJEdBqSpvPD-I&mime_type=video_mp4&qs=15&rc=Zjw5PDs3Zzs0PGk0NGk2OUBpM3k4Zmg6ZjN4bzMzNGkzM0AwYWFiYmBgXy8xYzJjMTAvYSNzNmxtcjRvXy9gLS1kLWFzcw%3D%3D&btag=e00008000&dy_q=1699096969&feature_id=d65f473b4463b6315c21eb3d7c571218&l=202311041922484BAFE337DE2DBCE29136
        - 通过 视频链接中的关键字<参数> 去搜索 视频链接是通过那个数据包生成出来
            https://www.douyin.com/user/MS4wLjABAAAAkzRSrOuSsM4Z1Ricsddumx_aSvX0jmOPcQR2qTs3PEtImBD8BomLrqvtIOBKOL0P?modal_id=7297492012008279334

二. 代码实现步骤
    1. 发送请求, 模拟浏览器对于url地址发送请求
    2. 获取数据, 获取服务器返回响应数据
    3. 解析数据, 提取 视频链接 / 视频标题
    4. 保存数据, 获取视频内容保存本地文件夹

- 模拟浏览器:
    为了防止被反爬 <得不到数据>

多个视频采集: 等会再讲

招生环节: 从零基础入门到项目实战系统课程内容
    加木子老师微信: python10080 免费领取学习路线图

系统课程内容:
    核心编程 爬虫开发 数据分析 网站开发 人工智能 自动化办公 JS逆向 VUE框架 GUI界面开发 BI专题...

专门针对python职业培训:
    关于python常用技术方向都会教学
学校教学类目多: 都是属于基础范围...

采集抖音数据 评论 视频 用户ID...
    实现JS逆向采集 --> 1000-2000左右
    采集某二手房源数据/二手车数据 作业简单作业 --> 200-300左右

2. 兼职外包: 核心编程 爬虫开发 数据分析
    实现副业接单/帮别人程序.... <外包多一些学生作业 爬虫+数据分析为主>
        外包单价: 200-5000左右
        外包收入: 在校学生 -> 1000-3000左右收入是OK的
    一周接1个外包 -> 一个外包均价200元左右 800元左右
    一周接1个外包 -> 一个外包均价400元左右 1600元左右

3. 就业工作: 核心编程 爬虫开发 数据分析 网站开发<前端+后端>
    岗位: 爬虫工程师 数据分析师 开发工程师 全栈开发
    薪资: 8000-15000左右

外包如何去接? 怎么接? <个人>
    - 淘宝 / 闲鱼
    - 外包接单平台
    - 外包接单群
    < 30%左右抽成 > 100外包, 收入70元

如果你跟着老师来学习 --> 提供相关外包资源给你 <附加服务内容>
    1. 只需要学完爬虫之后, 想要接单/外包 --> 可以直接私聊找我
        我能够给你一对一提供外包订单
    2. 内部外包接单群
        直接提供甲方客户 <所有收益归你自己所有>

外包不会像外包公司/工作室[不管价格 和 需求]那样一天十几二十个外包: 基本每天都会有外包...
    你刚开始接外包, 不会的我可以一对一提供给你...

主要教学服务: <让你掌握python相关知识点内容>
    让你掌握咱们知识点内容 + 在学习过程中有任何不懂地方,都可以直接找老师解答辅导

双11优惠活动,学费有一定减免
    兼职外包课程: 核心编程 爬虫开发 数据分析
        原价学费: 2260+2980+2180 = 7420
        优惠学费: 6680
        双11减免: 6080
        课程学费无压力学习: 申请分期免息学习 0利息0手续
            其实就是先学习, 后支付 <先进班学习, 学一个月支付一个月学费>
        先预定300元学费, 剩余 5780 学费, 可以申请3/6/9/12/18个月支付学费
            5780 / 18 = 321元/月左右
    报名三个阶段课程, 我额外再赠送三个课程给你 参与三次机会抽奖
        人工智能 自动化办公 JS逆向 VUE框架 GUI界面开发 BI专题 面试特训班

    高薪就业课程: 核心编程 爬虫开发 数据分析 网站开发
        原价学费: 2260+2980+2180+2980 = 10400
        优惠学费: 8880
        双11减免: 8080
        申请先后付: 8080 - 300 = 7780 / 24个月 = 324元/月
    额外赠送四个课程:
        人工智能 自动化办公 JS逆向 VUE框架 GUI界面开发 BI专题 面试特训班

预定300元学费, 办理好入学之后, 可以享受青灯教育老师教学服务:
    课程资料 源码 笔记 文档课件 老师辅导解答....
课程学习权限: 2年
    直播+老师辅导解答
课程资料权限: 永久
    2年 10年  咱们更新只要更新技术了, 你一样可以学习最新技术内容

加木子老师微信: python10080...
    今天报名课程跟着老师学习:
        自游老师一对一提供外包订单 <名额有限, 先到先得> 仅限5个同学

国家工信部证书: NACG python软件工程师证书 500元
    报名费用由青灯教育帮你承担 / 考试预约也是通过班主任预约
        只需要你本人去考试即可.... <学课程内容100%稳过的>

现在报名学费每个月320元左右
    达到接单外包水平:
        2个左右时间/学完爬虫之后 就开始接单了
        320元左右学费 相当于一个月接1-2个简单外包
        < 刚开始担心不会做外包, 自游老师手把手带你 教你如何去做>
    达到企业开发水平:
        掌握课程80%左右知识点, 就业工作....

在学习过程中 遇到任何不懂地方, 一定要多问老师, 不要觉得不好意思


自动化小脚本:
    1. 抢购脚本
    2. 自动发送弹幕 <弹幕机器人>
    3. 自动点赞 评论
    ...
网页 APP 软件 <客户端数据 PC 移动端>
    通过抓包工具 去抓包分析数据接口

"""
# 导入数据请求模块
import requests
# 导入正则表达式模块
import re
# 导入json模块
import json
# 导入格式化输出模块
from pprint import pprint
# 导入自动化测试模块
from selenium import webdriver
# 导入时间模块
import time
from selenium.webdriver.common.by import By
# import  
from textsa import downLoadWithUrl


# 创建 WebDriver 实例
# driver = webdriver.Chrome()

# 访问指定的 URL
# driver.get("https://www.example.com")
# time.sleep(200000)

def drop_down():
    """执行页面滚动的操作"""  # javascript
    for x in range(1, 12, 2):  # 1 3 5 7 9  在你不断的下拉过程中, 页面高度也会变的
        time.sleep(1)
        j = x / 9  # 1/9  3/9  5/9  9/9
        # document.documentElement.scrollTop  指定滚动条的位置
        # document.documentElement.scrollHeight 获取浏览器页面的最大高度
        js = 'document.documentElement.scrollTop = document.documentElement.scrollHeight * %f' % j
        driver.execute_script(js)


# https://www.douyin.com/user/MS4wLjABAAAAkzRSrOuSsM4Z1Ricsddumx_aSvX0jmOPcQR2qTs3PEtImBD8BomLrqvtIOBKOL0P?modal_id=7270434094058622267
"""批量采集视频"""
driver =  webdriver.Chrome() #WebDriver.Chrome()
driver.get('https://www.douyin.com/user/MS4wLjABAAAAkzRSrOuSsM4Z1Ricsddumx_aSvX0jmOPcQR2qTs3PEtImBD8BomLrqvtIOBKOL0P')
driver.implicitly_wait(20)
time.sleep(20)
drop_down()
# lis = driver.find_element(By.id,'.Eie04v01')
# lis = driver.find_element(By.CLASS_NAME,'GE_yTyVX')#e6wsjNLL bGEvyQfj
# print("lis")
# print(lis)
# list = driver.find_element(By.CLASS_NAME,'e6wsjNLL bGEvyQfj')#e6wsjNLL bGEvyQfj
# 使用 XPath 查找元素
# list  = driver.find_element(By.XPATH, "//ul[@class='e6wsjNLL bGEvyQfj']")
# print("list=")
# print(list)
# subitems = list.find_elements(By.CLASS_NAME,"niBfRBgX Q_uOVQ1u SBWUpJd_")
# print(subitems)
# li = list.find_elements(By.XPATH, "//li[@class='niBfRBgX Q_uOVQ1u SBWUpJd_']")
# print("li=/n\n")
# print(li)



driver_li = driver.find_elements(By.XPATH, "//li[@class='niBfRBgX Q_uOVQ1u SBWUpJd_']")
# print("driver_li")
# print(driver_li)
for li in driver_li:
    href = li.find_element(By.CSS_SELECTOR,'a').get_attribute('href')#推荐id
    video_id = href.split('/')[-1]
    print(video_id)
    
    downLoadWithUrl(video_id)
    # try:
    """发送请求"""
    # 请求链接  
    # url = f'https://www.douyin.com/user/MS4wLjABAAAAkzRSrOuSsM4Z1Ricsddumx_aSvX0jmOPcQR2qTs3PEtImBD8BomLrqvtIOBKOL0P?modal_id={video_id}'
    # # 模拟浏览器
    # headers = {
    #     'Cookie':'douyin.com; device_web_cpu_core=6; device_web_memory_size=8; architecture=amd64; ttwid=1%7C8G9r9pAsU1aFzyYoAs4EBGgadS1fnfN4y_SE0U2tIE4%7C1697284289%7C369d1bcedd8138537de4b27a0d7e3008ae22b227f75ad0419180418943ea2cb2; passport_csrf_token=def783dda3cef72e8aa8501bba5ebbee; passport_csrf_token_default=def783dda3cef72e8aa8501bba5ebbee; s_v_web_id=verify_lnpz8tcd_3XM8GNhT_C2e5_4oeW_9QQ1_IK6DhXGG8bsP; my_rd=2; webcast_local_quality=null; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A2560%2C%5C%22screen_height%5C%22%3A1440%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A6%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A50%7D%22; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%7D; strategyABtestKey=%221699096969.067%22; home_can_add_dy_2_desktop=%221%22; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCSjVLdHNDZXVEV3VqZmgzbVdadVFHbmt0N3d0UkZvZDVnaWwyeCtBWnpLQ1lhZjRPMFp1VmFEOVUrM0JPdzJKMDMzQnp4dnRDQTNybEc5TktPZEZrek09IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoxfQ%3D%3D; tt_scid=Mno41MB.hPdtiU56n66BAgjmiIsjkJxPjuFHELGCjJwS5.qHhAyaGyz1QDEV7Jwp74bf; download_guide=%221%2F20231104%2F0%22; pwa2=%220%7C0%7C1%7C0%22; msToken=t-1E36DVBPvQ-VI88HRX0r-bMp4W1RjgsOfMjbo0d0tb2d90jJex5nzwm4I3eWWZQ5V6Tob9FXrocb7CXN-FTivjsrLOEoKQAwfShjHv6j5MTamoihetw4kVqstdOKc=; volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Atrue%2C%22volume%22%3A0.5%7D; msToken=5l5rrpzXZ2w4JvVJzxN3tM0D8WwPB2kQceEpYXbsI_XbWd98evzAOXBb8F86XuPoTupybcTVaKjLs_kRmr5-ur3sctIE9mu3uAOTG7kRKrcskLBRB0LurKsn09uALZA=; IsDouyinActive=false; __ac_nonce=06546354d00ccccfb94ee; __ac_signature=_02B4Z6wo00f01xhdY5gAAIDDmF-Z2bS5EV8YfWcAAKNbomfW3IMANqI2B9teCFXf2JYJnZFMyiomo3r.kRbkUITTnxiy2P4KrDBrlpv3QdhAmmoeEx1WR3W8OyGR1Lo0S-Dysh6wmfCN7tjY8a; __ac_referer=https://www.douyin.com/user/MS4wLjABAAAAkzRSrOuSsM4Z1Ricsddumx_aSvX0jmOPcQR2qTs3PEtImBD8BomLrqvtIOBKOL0P',
    #     'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
    # }
    # # 发送请求
    # response = requests.get(url=url, headers=headers)
    # response.encoding = 'utf-8'
    # """获取响应数据"""
    # html_data = response.text
    # """解析数据"""
    
    # # print("html_data=============")
    # # print(html_data)
    # # 提取标题
    # # restring = '\\\"desc\\\":\\\"(.*?)\\\",'
    # restring = '\"desc\":\"(.*?)\",'
    # print(restring)
    # obj = re.compile(r'\"desc\":\"(.*?)\",')
    # old_title = obj.findall(html_data)
    
    # # old_title = re.findall('video_title" content="(.*?)"/>', html_data)[0]
    # print(old_title)
    # # 替换特殊字符
    # title =  old_title#re.sub(r'[\\/:*"?<>|\n]', '', old_title)
    # print("title = ")
    # print(title)
    # # 视频链接信息
    # result = re.findall('<script id="RENDER_DATA" type="application/json">(.*?)</script>', html_data)[0]
    # # 解码
    # info = requests.utils.unquote(result)
    # # 转成json字典
    # json_data = json.loads(info)
    # # 提取视频链接 -> 字符串拼接 + 字典取值 + 列表索引取值
    # video_url = 'https:' + json_data['app']['videoDetail']['video']['bitRateList'][0]['playAddr'][0]['src']
    # print("video_url")
    # print(video_url)
    # """保存数据"""
    # # 获取视频内容
    # video_content = requests.get(url=video_url, headers=headers).content
    # with open('/video/' + title + '.mp4', mode='wb') as f:
    #     f.write(video_content)
    # print(title)
    # pprint(video_url)
    # except:
    pass